package com.ch07.container;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName ContainerFACTORY
 * @Description 容器工厂
 * 作业：实现容器工厂
 * 1. 自定义@Component注解，用于标注在类上
 * 2. 创建容器工厂ContainerFactory，负责管理和创建所有的对象
 *       在初始化ContainerFactory时，必须先将项目中所有标注了@Component注解的类创建好并存放到ContainerFactory的容器中
 * 3.   ContainerFactory需要提供一个getBean(String name)
 *        方法负责从容器中获取对象
 * @Author Kx
 * @Date 2025/4/15 11:42
 * @Version 1.0
 */
public class ContainerFactory {
    /***
     * @author: kx
     * @date: 2025/4/16 8:41
     * @description: 容器, 用来存储所有有@Component注解的类
    */
    private final Map<String,Object> map = new HashMap<>();

    /***
     * @author: kx
     * @date: 2025/4/16 10:55
     * @description: 初始化注入属性处理器
    */
    private final FieldInjectHandler fieldInjectHandler = new FieldInjectHandler();

    /***
     * @author: kx
     * @date: 2025/4/16 10:32
     * @param packageName : 包名
     * @description: 查询指定包名下有@Component注解的类
    */
    public ContainerFactory(String packageName) {
        ContainerFactoryUtil containerFactoryUtil = new ContainerFactoryUtil();
        // 调用方法获取有注解的类
        containerFactoryUtil.ComponentScanner(packageName, map);

        // 给所有的类进行属性注入
        processInject();
    }

    /***
     * @author: kx
     * @date: 2025/4/16 10:31
     * @description: 默认查询项目下所有有@Component注解的类
    */
    public ContainerFactory() {
        ContainerFactoryUtil containerFactoryUtil = new ContainerFactoryUtil();
        // 调用方法获取有注解的类
        containerFactoryUtil.ComponentScanner(map);
    }

    /***
     * @author: kx
     * @date: 2025/4/16 10:56
     * @description: 给所有的类进行属性注入
    */
    private void processInject() {
        // 遍历集合中的key值
        for (String key : map.keySet()) {
            fieldInjectHandler.handle(map.get(key), this);
        }
    }

    /***
     * @author: kx
     * @date: 2025/4/15 19:14
     * @param name : 类名
     * @return java.lang.Class<?>
     * @description: 根据类名获取类对象
    */
    public Object getBean(String name) {
        // 判断容器中是否有该类
        if (map.containsKey(name)) {
            return map.get(name);
        }
        throw new RuntimeException("没有这个类" + name);
    }
}
